﻿using Apps.Common;
using Apps.IService;
using Apps.Model;
using Apps.Repository;
using Apps.Repository.UnitOfWork;
using AutoMapper;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Apps.Service
{
    public class BaseService<TEntity, TKey> : IBaseService<TEntity, TKey> where TEntity : class, IEntity<TKey>
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IBaseRepository<TEntity, TKey> _repository;
        protected readonly IMapper _mapper;
        public BaseService(IUnitOfWork unitOfWork, IMapper mapper)
        {
            _unitOfWork = unitOfWork;
            _repository = _unitOfWork.GetRepository<TEntity, TKey>();
            _mapper = mapper;
        }

        public async Task<int> AddAsync(TEntity entity)
        {
            await _repository.AddAsync(entity);
            return await _unitOfWork.SaveChangesAsync();

        }

        public async Task AddRangeAsync(IEnumerable<TEntity> entities)
        {
            await _repository.AddRangeAsync(entities);
        }

        public async Task<int> DeleteAsync(TEntity entity)
        {
            await _repository.DeleteAsync(entity);
            return await _unitOfWork.SaveChangesAsync();
        }

        public async Task DeleteRangeAsync(IEnumerable<TEntity> entities)
        {
            await _repository.DeleteRangeAsync(entities);
            await _unitOfWork.SaveChangesAsync();
        }

        public async Task<bool> ExistsAsync(Expression<Func<TEntity, bool>> predicate)
        {
            return await _repository.ExistsAsync(predicate);
        }

        public Task<List<TEntity>> GetAllAsync()
        {
            return _repository.GetAllAsync();
        }

        public async Task<IEnumerable<TEntity>> GetAsync(Expression<Func<TEntity, bool>> predicate)
        {
            return await _repository.GetAsync(predicate);
        }

        public async Task<TEntity> GetByIdAsync(TKey id)
        {
            return await _repository.GetByIdAsync(id);
        }

        public async Task<PagedResult<TEntity>> GetPagedAsync(int pageIndex, int pageSize, Expression<Func<TEntity, bool>> predicate = null) 
        {
            return await _repository.GetPagedAsync(pageIndex, pageSize, predicate);
        }

        public async Task<int> UpdateAsync(TEntity entity)
        {
            await _repository.UpdateAsync(entity);
            return await _unitOfWork.SaveChangesAsync();
        }

        public async Task UpdateRangeAsync(IEnumerable<TEntity> entities)
        {
            await _repository.UpdateRangeAsync(entities);
            await _unitOfWork.SaveChangesAsync();
        }

        // 新增通用映射方法
        protected TDestination MapTo<TDestination>(TEntity source)
        {
            return _mapper.Map<TDestination>(source);
        }

        // 新增分页结果映射方法
        protected PagedResult<TDestination> MapPagedResult<TDestination>(PagedResult<TEntity> source)
        {
            return new PagedResult<TDestination>(
                _mapper.Map<List<TDestination>>(source.Items),
                source.TotalCount,
                source.PageNumber,
                source.PageSize
            );
        }
    }
}
